<template>
  <div class="video-call">
    <div class="video-wrapper">
      <!-- 本地视频外层容器 -->
      <div ref="localContainer" class="video-container local-container">
        <div ref="localVideo" id="local-video" class="local-video"></div>
      </div>
      <!-- 远程视频外层容器 -->
      <div
        ref="remoteContainer"
        class="video-container remote-container"
        v-show="isVideoStarted"
        @mousedown="dragStart"
        @dblclick="swapVideos"
      >
        <div ref="remoteVideo" id="remote-video" class="remote-video"></div>
      </div>
    </div>

    <!--按钮-->
    <div id="button-container" :class="{ chatShifted: isChatVisible,seatShifted:isSeatVisible }">
      <!--文件上传-->
      <button class="button" id="youtube" @click="toggleSidePanel">
        <i class="fa-solid fa-file"></i>
      </button>
      <!--拉流-->
      <button class="button" id="github" @click="startRemoteStream">
        <i class="fa-solid fa-download"></i>
      </button>
      <!--批注-->
      <button class="button" id="dribbble" @click="toggleSidePanel2">
        <i class="fa-solid fa-pen"></i>
      </button>
      <!--视频-->
      <button class="button" id="instagram" @click="startVideo">
        <i class="fa-solid fa-video"></i>
      </button>
      <!--屏幕共享-->
      <button class="button" id="facebook" @click="toggleScreenShare">
        <i class="fa-solid fa-desktop"></i>
      </button>
      <!--初始按钮-->
      <button class="button" id="share">
        <i class="fa-solid fa-ellipsis-vertical"></i>
      </button>
    </div>

    <!-- 整合后的聊天系统 -->
    <div class="chat-system" :class="{ active: isChatVisible }">
      <div class="chat-panel">
        <div class="chat-messages" ref="messageContainer">
          <div
            v-for="(message, index) in messageList"
            :key="index"
            class="message-item"
          >
            <span class="message-time">{{ message.time }}</span>
            <span class="message-user">{{ message.user }}:</span>
            <span class="message-content">{{ message.content }}</span>
          </div>
        </div>

        <div class="chat-input">
          <input
            v-model="messageInput"
            type="text"
            placeholder="输入消息（最多1024字节）"
            @keyup.enter="sendMessage"
          />
          <button @click="sendMessage">发送</button>
        </div>
      </div>
    </div>

    <div class="seat-system" :class="{ active: isSeatVisible }">
      <div class="seat-panel">
        <seat-table v-if="isSeatVisible" v-loading="isLoading" :matrix-data="seatTable.seats" :rows="seatTable.rowNum" :cols="seatTable.colNum"></seat-table>
      </div>
    </div>

    <!-- 聊天触发按钮 -->
    <div
      class="chat-trigger"
      @click="toggleChat"
      :class="{ active: isChatVisible }"
    >
      <i class="fa-solid fa-comments"></i>
    </div>

    <div
        v-if="!isOnline"
        class="seat-trigger"
        @click="toggleSeat"
        :class="{ active: isSeatVisible }"
    >
      <i class="fa-solid fa-user"></i>
    </div>

    <!-- 投票窗口 -->
    <div class="vote-window" v-show="isVoteWindowVisible">
      <div class="vote-content">
        <h2>投票</h2>
        <div v-for="(option, index) in voteOptions" :key="index">
          <input type="checkbox" v-model="selectedOptions" :value="option" />
          {{ option }}
        </div>
        <button @click="submitVote">投票</button>
      </div>
    </div>

    <!-- 侧拉框 -->
    <div class="side-panel" :class="{ active: isSidePanelVisible }">
      <meetFile style="height: 100%" ref="meetingFileRef"></meetFile>
    </div>
    <div class="side-panel" :class="{ active: isSidePanelVisible2 }">
      <PDFvue></PDFvue>
    </div>
  </div>
</template>

<script>
import { ZegoExpressEngine } from "zego-express-engine-webrtc";
import axios from "axios";
import "@fortawesome/fontawesome-free/css/all.css";
import meetFile from "../../components/meetFile.vue";
import PDFvue from "../../components/PDFvue.vue";
import SeatTable from "@/components/seatTable.vue";
import {ElMessage} from "element-plus";
export default {
  components: {
    SeatTable,
    meetFile,
    PDFvue,
  },
  data() {
    return {
      seatTable: {},
      isOnline:true,
      localContainer: null,
      remoteContainer: null,
      localVideo: null,
      remoteVideo: null,
      isScreenShared: false,
      localStream: null,
      remoteStream: null,
      videoSharing: null,
      offsetX: 0,
      offsetY: 0,
      isDragging: false,
      messageInput: "",
      messageList: [],
      messageContainer: null,
      isChatVisible: false,
      isSeatVisible:false,
      isLoading:false,
      appID: 432857160,
      server: "wss://webliveroom432857160-api.imzego.com/ws",
      userID: "",
      userName: "",
      roomID: "",
      token: "",
      zg: null,
      isVideoStarted: false,
      streamID: "", // 视频流 ID
      screenStreamID: "", // 屏幕共享流 ID
      voteOptions: ["选项1", "选项2", "选项3", "选项4"],
      selectedOptions: [],
      isVoteWindowVisible: false, // 初始时投票窗口隐藏
      meetingStatus: "",
      mediaRecorder: null, // 用于录音的对象
      audioChunks: [], // 用于存储录音数据的数组
      isRecording: false, // 是否正在录音
      queryInterval: null, // 用于存储轮询定时器的引用
      isSidePanelVisible: false, // 控制侧拉框的显示
      isPolling: false, // 轮询控制
      isSidePanelVisible2: false
    };
  },
  mounted() {
    try {
      this.getUrlParams();
      // 设置轮询
      this.queryInterval = setInterval(() => {
        this.query();
      }, 60000); // 60000 毫秒（60 秒）轮询一次
    } catch (error) {
      console.error("mounted error:", error);
    }
  },
  beforeDestroy() {
    try {
      document.removeEventListener("mousemove", this.drag);
      document.removeEventListener("mouseup", this.dragEnd);
      // 清除轮询定时器
      if (this.queryInterval) {
        clearInterval(this.queryInterval);
      }
    } catch (error) {
      console.error("beforeDestroy error:", error);
    }
  },
  methods: {
    getUrlParams() {
      try {
        const urlParams = new URLSearchParams(
          window.location.hash.split("?")[1]
        );
        const linkId = urlParams.get("linkId");
        const userId = urlParams.get("userId");
        if (linkId) {
          this.roomID = linkId;
          this.streamID = linkId;
          this.screenStreamID = `${this.streamID}1`;
          this.$refs.meetingFileRef.initTable(this.roomID, userId);
        }
        if (userId) {
          this.userID = userId;
          this.userName = userId;
        }
        this.zg = new ZegoExpressEngine(this.appID, this.server);
        this.zg.setDebugVerbose(true);
        this.query();
      } catch (error) {
        console.error("getUrlParams error:", error);
      }
    },
    loginRoom() {
      try {
        if (!this.token) {
          console.error("Token is empty, cannot login room.");
          return;
        }
        this.zg
          .loginRoom(
            this.roomID,
            this.token,
            { userID: this.userID, userName: this.userName },
            { userUpdate: true }
          )
          .then(() => {
            console.log("成功登录房间");
          })
          .catch((error) => {
            console.error("登录房间失败：", error);
          });
      } catch (error) {
        console.error("loginRoom error:", error);
      }
    },
    dragStart(event) {
      try {
        this.offsetX =
          event.clientX -
          this.$refs.remoteContainer.getBoundingClientRect().left;
        this.offsetY =
          event.clientY -
          this.$refs.remoteContainer.getBoundingClientRect().top;
        this.isDragging = true;
        document.addEventListener("mousemove", this.drag);
        document.addEventListener("mouseup", this.dragEnd);
      } catch (error) {
        console.error("dragStart error:", error);
      }
    },
    drag(event) {
      try {
        if (this.isDragging) {
          let newLeft = event.clientX - this.offsetX;
          let newTop = event.clientY - this.offsetY;
          const wrapperRect =
            this.$refs.remoteContainer.parentElement.getBoundingClientRect();
          const maxWidth =
            wrapperRect.width - this.$refs.remoteContainer.offsetWidth;
          const maxHeight =
            wrapperRect.height - this.$refs.remoteContainer.offsetHeight;
          newLeft = Math.max(0, Math.min(newLeft, maxWidth));
          newTop = Math.max(0, Math.min(newTop, maxHeight));
          this.$refs.remoteContainer.style.left = `${newLeft}px`;
          this.$refs.remoteContainer.style.top = `${newTop}px`;
        }
      } catch (error) {
        console.error("drag error:", error);
      }
    },
    dragEnd() {
      try {
        this.isDragging = false;
        document.removeEventListener("mousemove", this.drag);
        document.removeEventListener("mouseup", this.dragEnd);
      } catch (error) {
        console.error("dragEnd error:", error);
      }
    },
    swapVideos() {
      try {
        const localParent = this.$refs.localVideo.parentNode;
        const remoteParent = this.$refs.remoteVideo.parentNode;
        localParent.appendChild(this.$refs.remoteVideo);
        remoteParent.appendChild(this.$refs.localVideo);
      } catch (error) {
        console.error("swapVideos error:", error);
      }
    },
    startVideo() {
      try {
        if (!this.isVideoStarted) {
          // 创建视频流
          this.zg
            .createZegoStream()
            .then((stream) => {
              this.localStream = stream;
              stream.playVideo(this.$refs.remoteVideo, {
                enableAutoplayDialog: true,
              });
              this.zg.startPublishingStream(this.streamID, stream);

              // 开始录音
              this.startRecording();

              this.isVideoStarted = true;
              console.log("视频流开始，流ID：", this.streamID);
            })
            .catch((error) => {
              console.error("开始视频流失败：", error);
            });
        } else {
          // 停止视频流
          this.zg.stopPublishingStream(this.streamID);
          this.zg.destroyStream(this.localStream);
          this.localStream = null;

          // 停止录音并保存
          this.stopRecording();

          this.isVideoStarted = false;
          console.log("视频流已停止并销毁");
        }
      } catch (error) {
        console.error("startVideo error:", error);
      }
    },
    startRemoteStream() {
      try {
        // 如果已经有拉流在进行，直接停止所有拉流
        if (this.remoteStream) {
          console.log("检测到已有拉流，直接停止所有拉流");
          // 停止屏幕共享流
          if (this.screenStreamID) {
            this.zg.stopPlayingStream(this.screenStreamID);
            this.zg.destroyStream(this.screenStreamID);
          }
          // 停止视频流
          if (this.streamID) {
            this.zg.stopPlayingStream(this.streamID);
            this.zg.destroyStream(this.streamID);
          }
          this.remoteStream = null;
          this.isVideoStarted = false; // 更新状态
          return; // 直接返回，不再执行后续拉流逻辑
        }

        // 如果没有拉流，执行拉流逻辑
        // 拉取屏幕共享流

          this.zg
            .startPlayingStream(this.screenStreamID)
            .then((stream) => {
              this.remoteStream = stream;
              const remoteView = this.zg.createRemoteStreamView(stream);
              remoteView.play(this.$refs.localVideo, {
                enableAutoplayDialog: true,
              });
              console.log("屏幕共享流拉取成功，流ID：", this.screenStreamID);
            })
            .catch((error) => {
              console.error("屏幕共享流拉取失败：", error);
            });


        // 拉取视频流

          this.zg
            .startPlayingStream(this.streamID)
            .then((stream) => {
              this.remoteStream = stream;
              const remoteView = this.zg.createRemoteStreamView(stream);
              remoteView.play(this.$refs.remoteVideo, {
                enableAutoplayDialog: true,
              });
              this.isVideoStarted = true;
              console.log("视频流拉取成功，流ID：", this.streamID);
            })
            .catch((error) => {
              console.error("视频流拉取失败：", error);
            });
        } catch (error) {
          console.error("startRemoteStream error:", error);
        }

    },
    startScreenShare() {
      try {
        const screenWidth = document.getElementById("screenWidth")
          ? parseInt(document.getElementById("screenWidth").value, 10)
          : window.innerWidth;
        const screenHeight = document.getElementById("screenHeight")
          ? parseInt(document.getElementById("screenHeight").value, 10)
          : window.innerHeight;

        this.zg
          .createZegoStream({
            videoBitrate: 1500,
            screen: {
              audio: this.$refs.localVideo === "yes" ? true : false,
              video: {
                quality: 4,
                frameRate: 15,
                width: screenWidth,
                height: screenHeight,
              },
            },
          })
          .then((stream) => {
            this.videoSharing = stream;
            stream.playVideo(this.$refs.localVideo, {
              enableAutoplayDialog: true,
            });
            // 为屏幕共享流分配一个新的 streamID

            this.zg.startPublishingStream(this.screenStreamID, stream);
            console.log("屏幕共享开始，流ID：", this.screenStreamID);
          })
          .catch((error) => {
            console.error("开始屏幕共享失败：", error);
          });
      } catch (error) {
        console.error("startScreenShare error:", error);
      }
    },
    stopScreenShare() {
      try {
        if (this.videoSharing) {
          this.zg.stopPublishingStream(this.streamID);
          this.zg.destroyStream(this.videoSharing);
          this.videoSharing = null;
          console.log("屏幕共享已停止");
        }
      } catch (error) {
        console.error("stopScreenShare error:", error);
      }
    },
    toggleScreenShare() {
      try {
        if (!this.isScreenShared) {
          this.startScreenShare();
          this.isScreenShared = true;
        } else {
          this.stopScreenShare();
          this.isScreenShared = false;
        }
      } catch (error) {
        console.error("toggleScreenShare error:", error);
      }
    },
    toggleChat() {
      try {
        if(this.isChatVisible){
          this.isChatVisible=false;
        }
        else {
          this.isChatVisible=true;
          this.isSeatVisible=false;
        }
      } catch (error) {
        console.error("toggleChat error:", error);
      }
    },
    toggleSeat() {
      try {
        if(this.isSeatVisible){
          this.isSeatVisible=false;
        }
        else {
          this.initSeatTable();
          this.isChatVisible=false;
        }
      } catch (error) {
        console.error("toggleSeat error:", error);
      }
    },
    initSeatTable(){
      this.$http.get("/meeting/room/seat/table?meetingId="+this.roomID)
          .then((response) => {
            if(response.data.code===200){
              this.seatTable=response.data.data;
              this.isSeatVisible=true;
            }
            else {
              ElMessage.error(response.data.msg);
            }
          });
    },
    submitVote() {
      try {
        console.log("投票结果：", this.selectedOptions);
        this.isVoteWindowVisible = false;
      } catch (error) {
        console.error("submitVote error:", error);
      }
    },
    getToken() {
      try {
        const formData = new FormData();
        formData.append("userId", this.userID);
        axios
          .post("/streaming/roomManager/getToKen", formData)
          .then((response) => {
            console.log("Token request response:", response);
            if (response.data.code === 200) {
              if (response.data.data) {
                this.token = response.data.data.data;
                this.loginRoom();
                this.listenMessages();
              } else {
                console.error("Token data is empty in the response.");
              }
            } else {
              console.error("Token request failed:", response.data.msg);
            }
          })
          .catch((error) => {
            console.error("Token request error:", error);
          });
      } catch (error) {
        console.error("getToken error:", error);
      }
    },
    query() {
      try {
        axios
          .get("/meeting/meeting/online/query/" + this.roomID)
          .then((response) => {
            if (response.data.code === 200) {
              if (response.data.data) {
                this.meetingStatus = response.data.data.meeting.meetingStatus;
                this.isOnline=response.data.data.meetingType==='线上';
                if (this.meetingStatus != 2 && this.isPolling == false) {
                  this.getToken();
                  this.isPolling = true;
                }
                if (this.meetingStatus == 2 && this.isPolling == true) {
                  // 停止视频流
                  this.zg.stopPublishingStream(this.streamID);
                  this.zg.destroyStream(this.localStream);
                  this.localStream = null;
                  // 停止录音并保存
                  this.stopRecording();
                  this.isVideoStarted = false;
                  console.log("视频流已停止并销毁");

                  //结束屏幕共享
                  this.stopScreenShare();
                  this.isScreenShared = false;
                  this.isPolling = false;
                }
                if (this.meetingStatus == 2 && this.isPolling == false) {
                  this.$message.error("会议未开始");
                }
              } else {
                console.error("Token data is empty in the response.");
              }
            } else {
              this.$message.error("没有该会议");
            }
          })
          .catch((error) => {
            console.error("Token request error:", error);
          });
      } catch (error) {
        console.error("query error:", error);
      }
    },
    startRecording() {
      try {
        // 请求音频输入权限
        navigator.mediaDevices
          .getUserMedia({ audio: true })
          .then((stream) => {
            this.mediaRecorder = new MediaRecorder(stream);
            this.audioChunks = []; // 清空之前的录音数据
            this.mediaRecorder.ondataavailable = (event) => {
              if (event.data.size > 0) {
                this.audioChunks.push(event.data);
              }
            };
            this.mediaRecorder.start();
            this.isRecording = true;
            console.log("录音开始");
          })
          .catch((error) => {
            console.error("无法获取音频输入：", error);
          });
      } catch (error) {
        console.error("startRecording error:", error);
      }
    },
    stopRecording() {
      try {
        if (this.mediaRecorder) {
          this.mediaRecorder.stop();
          this.mediaRecorder.onstop = () => {
            // 合并录音数据
            const audioBlob = new Blob(this.audioChunks, {
              type: "audio/mpeg",
            });

            // 将 Blob 转换为 File 对象
            const audioFile = new File([audioBlob], `${this.roomID}.mp3`, {
              type: "audio/mpeg",
            });

            // 创建 FormData
            const formData = new FormData();
            formData.append(
              "fileName",
              `/ecm/${this.roomID}/${this.roomID}.mp3`
            );
            formData.append("multipartFile", audioFile);

            // 调用接口上传文件
            axios
              .post("/file/file/upload", formData)
              .then((response) => {
                console.log("文件上传成功：", response);
                if (response.data.code === 200) {
                  console.log(
                    "文件上传成功，服务器返回数据：",
                    response.data.data
                  );
                } else {
                  console.error("文件上传失败：", response.data.msg);
                }
              })
              .catch((error) => {
                console.error("文件上传失败：", error);
              });

            console.log("录音文件已保存为：", `${this.roomID}.mp3`);
          };
          this.isRecording = false;
        }
      } catch (error) {
        console.error("stopRecording error:", error);
      }
    },
    toggleSidePanel() {
      this.isSidePanelVisible = !this.isSidePanelVisible;
    },
    toggleSidePanel2() {
      this.isSidePanelVisible2 = !this.isSidePanelVisible2;
    },

    // 聊天窗口
    sendMessage() {
      try {
        if (!this.messageInput.trim()) return; // 如果消息为空，不发送
        this.zg
          .sendBarrageMessage(this.roomID, this.messageInput)
          .then((result) => {
            if (result.errorCode === 0) {
              this.addMessage({
                type: "sent",
                user: this.userName,
                content: this.messageInput,
              });
              this.messageInput = ""; // 清空输入框
            }
          })
          .catch((error) => {
            console.error("消息发送失败:", error);
          });
      } catch (error) {
        console.error(error);
      }
    },
    addMessage(message) {
      try {
        this.messageList.push({
          ...message,
          time: new Date().toLocaleTimeString(),
        });
        this.$nextTick(() => {
          if (this.$refs.messageContainer) {
            this.$refs.messageContainer.scrollTop =
              this.$refs.messageContainer.scrollHeight;
          }
        });
      } catch (error) {
        console.error(error);
      }
    },
    listenMessages() {
      try {
        this.zg.on("IMRecvBroadcastMessage", (roomID, messages) => {
          messages.forEach((msg) => {
            this.addMessage({
              type: "broadcast",
              user: msg.fromUser.userName,
              content: msg.message,
            });
          });
        });
        this.zg.on("IMRecvBarrageMessage", (roomID, messages) => {
          messages.forEach((msg) => {
            this.addMessage({
              type: "barrage",
              user: msg.fromUser.userName,
              content: msg.message,
            });
          });
        });
        this.zg.on("screenSharingEnded", (stream) => {
          console.warn("screen sharing end");
        });
      } catch (error) {
        console.error(error);
      }
    },
  },
};
</script>

<style scoped>
.video-call {
  margin-top: -3.5%;
  display: flex;
  flex-direction: column;
  height: 98vh;
  width: 99vw;
  justify-content: space-between;
  padding: 0;
  box-sizing: border-box;
  overflow: hidden;
  position: relative;
}

.video-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  z-index: 1;
}

.video-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.local-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.remote-container {
  position: absolute;
  top: 78%;
  left: 10px;
  width: 200px;
  height: 150px;
  z-index: 10;
  border: 2px solid #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  cursor: grab;
  user-select: none;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}

.remote-container:active {
  cursor: grabbing;
}

.local-video {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

.remote-video {
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

#button-container {
  position: fixed;
  top: 85%;
  left: 90%;
  transform: translate(-50%, -50%);
  z-index: 1001;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#button-container.chatShifted {
  left: calc(90% - 300px);
  transform: translate(0, -50%);
}

#button-container.seatShifted {
  left: calc(90% - 1020px);
  transform: translate(0, -50%);
}

.button {
  position: absolute;
  top: 10%;
  left: 50%;
  translate: -50% 50%;
  background: #f4f7f5;
  border: 1px solid #fbe6ed;
  border-radius: 25px;
  height: 50px;
  width: 50px;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: 0.3s ease-in;
}

#share {
  color: #dc0654;
  background: #fbe6ed;
}

#facebook {
  background: linear-gradient(-160deg, #00d2ff, #3a7bd5);
}

#instagram {
  background: linear-gradient(135deg, #833ab4, #fd1d1d, #fcb045);
}

#dribbble {
  background: linear-gradient(-70deg, #d70652, #ff025e);
}

#github {
  background: linear-gradient(-70deg, #171515, #ff025e);
}

#youtube {
  background: #ff0000;
}

#button-container:hover button {
  rotate: 360deg;
}

#button-container:hover #share {
  rotate: 270deg;
}

#button-container:hover > #facebook {
  translate: -200% 50%;
}

#button-container:hover > #instagram {
  translate: -150% -50%;
}

#button-container:hover > #dribbble {
  translate: -50% -100%;
}

#button-container:hover > #github {
  translate: 50% -50%;
}

#button-container:hover > #youtube {
  translate: 100% 50%;
}

.el-icon-video-camera {
  width: 25px;
  height: 25px;
}

.chat-panel {
  padding: 15px;
}

.chat-messages {
  height: 300px;
  overflow-y: auto;
  margin-bottom: 15px;
  background: #f8f9fa;
  border-radius: 6px;
  padding: 10px;
}

.message-item {
  margin: 8px 0;
  padding: 8px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  line-height: 1.4;
}

.message-time {
  font-size: 0.8em;
  color: #666;
  margin-right: 8px;
}

.message-user {
  font-weight: 1000;
  color: #007bff;
}

.message-content {
  color: #333;
}

.chat-input {
  display: flex;
  gap: 10px;
}

.chat-input input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 20px;
  outline: none;
}

.chat-input button {
  padding: 8px 20px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 20px;
  cursor: pointer;
  transition: background 0.2s;
}

.chat-input button:hover {
  background: #0056b3;
}

.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.chat-messages::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.chat-trigger {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 20px 0 0 20px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 1001;
  transition: all 0.3s ease;
}

.chat-trigger:hover {
  background: #ffffff;
  right: -2px;
}

.chat-trigger .el-icon {
  font-size: 20px;
  color: #606266;
}

.seat-trigger {
  position: fixed;
  right: 0;
  top: 55%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 20px 0 0 20px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 1001;
  transition: all 0.3s ease;
}

.seat-trigger:hover {
  background: #ffffff;
  right: -2px;
}

.seat-trigger .el-icon {
  font-size: 20px;
  color: #606266;
}

.chat-system {
  position: fixed;
  top: 0;
  right: -300px;
  width: 300px;
  height: 100vh;
  background: rgba(255, 255, 255, 0.98);
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 1000;
}

.chat-system.active {
  right: 0;
}

.chat-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.chat-messages {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
}

.message-item {
  margin: 10px 0;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.message-item:hover {
  transform: translateX(5px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.chat-input {
  padding: 15px;
  border-top: 1px solid #eee;
}

.seat-system {
  position: fixed;
  top: 0;
  right: -1020px;
  width: 1020px;
  height: 100vh;
  background: rgba(255, 255, 255, 0.98);
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 1000;
}

.seat-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.seat-system.active {
  right: 0;
}

.vote-window {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1002;
}

.vote-content {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

.vote-content h2 {
  margin-bottom: 10px;
}

.vote-content div {
  margin-bottom: 8px;
}

.vote-content button {
  margin-top: 10px;
  padding: 8px 20px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 20px;
  cursor: pointer;
  transition: background 0.2s;
}

.vote-content button:hover {
  background: #0056b3;
}
/* 文件侧拉框样式 */
.side-panel {
  position: fixed;
  top: 0;
  right: -1000px; /* 初始时隐藏在右侧 */
  width: 1000px;
  height: 100vh;
  background: rgba(255, 255, 255, 0.98);
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 1000;
}

.side-panel.active {
  right: 0; /* 显示时移动到右侧 */
}

/* 聊天样式 */
.chat-system {
  position: fixed;
  top: 0;
  right: -300px;
  width: 300px;
  height: 100vh;
  background: rgba(255, 255, 255, 0.98);
  box-shadow: -2px 0 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 1000;
}

.chat-system.active {
  right: 0;
}

.chat-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.chat-messages {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
}

.message-item {
  margin: 10px 0;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.message-item:hover {
  transform: translateX(5px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.chat-input {
  padding: 15px;
  border-top: 1px solid #eee;
}

.chat-trigger {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 20px 0 0 20px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 1001;
  transition: all 0.3s ease;
}

.chat-trigger:hover {
  background: #ffffff;
  right: -2px;
}

.chat-trigger .el-icon {
  font-size: 20px;
  color: #606266;
}
</style>